package edu.sdjzu.exam.service.exam.impl;

import edu.sdjzu.exam.domain.exam.ExamAnswer;
import edu.sdjzu.exam.domain.exam.ExamQuestion;
import edu.sdjzu.exam.domain.question.Question;
import edu.sdjzu.exam.domain.question.QuestionOption;
import edu.sdjzu.exam.enums.QuestionType;
import edu.sdjzu.exam.mapper.exam.ExamAnswersMapper;
import edu.sdjzu.exam.mapper.exam.ExamQuestionsMapper;
import edu.sdjzu.exam.mapper.QuestionMapper;
import edu.sdjzu.exam.mapper.QuestionOptionsMapper;
import edu.sdjzu.exam.service.exam.AutoGradingService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class AutoGradingServiceImpl implements AutoGradingService {

    private final ExamAnswersMapper examAnswersMapper;
    private final ExamQuestionsMapper examQuestionsMapper;
    private final QuestionMapper questionMapper;
    private final QuestionOptionsMapper questionOptionsMapper;

    // 系统自动判卷的ID标识
    private static final Long SYSTEM_GRADER_ID = 0L;

/**
     * 支持自动判卷的题目类型
     */
    private static final Set<String> AUTO_GRADABLE_TYPES = Set.of(
            "single_choice",
            "multiple_choice"
    );

    @Override
    @Transactional
    public AutoGradingResult autoGradeExam(Long examId, Long studentId) {
        log.info("开始自动判卷 - 考试ID: {}, 学生ID: {}", examId, studentId);

        // 1. 获取学生本次考试的所有答案
        List<ExamAnswer> answers = examAnswersMapper.selectAnswersByExamAndStudent(examId, studentId);
        if (answers.isEmpty()) {
            log.warn("未找到学生的答案记录 - 考试ID: {}, 学生ID: {}", examId, studentId);
            return createEmptyResult();
        }

        AutoGradingResult result = new AutoGradingResult();
        result.setTotalQuestions(answers.size());
        int autoGradedCount = 0;
        int manualGradedCount = 0;
        double totalScore = 0.0;
        double maxScore = 0.0;

        // 2. 遍历每个答案进行判卷
        for (ExamAnswer answer : answers) {
            try {
                // 获取题目信息
                Question question = questionMapper.selectQuestionById(answer.getQuestionId());
                if (question == null) {
                    log.warn("题目不存在 - 题目ID: {}", answer.getQuestionId());
                    continue;
                }

                // 获取考试题目信息（包含分值）
                ExamQuestion examQuestion = examQuestionsMapper.selectExamQuestionByExamAndQuestion(examId, answer.getQuestionId());
                if (examQuestion == null) {
                    log.warn("考试题目配置不存在 - 考试ID: {}, 题目ID: {}", examId, answer.getQuestionId());
                    continue;
                }

                double questionPoints = examQuestion.getScore().doubleValue();
                maxScore += questionPoints;

                // 判断题目类型是否支持自动判卷
                if (AUTO_GRADABLE_TYPES.contains(question.getQuestionType())) {
                    // 自动判卷
                    double score = gradeObjectiveQuestion(question, answer, questionPoints);
                    updateAnswerScore(answer.getAnswerId(), score, SYSTEM_GRADER_ID, LocalDateTime.now(), null);
                    totalScore += score;
                    autoGradedCount++;
                    log.debug("自动判卷完成 - 题目ID: {}, 得分: {}/{}", answer.getQuestionId(), score, questionPoints);
                } else {
                    // 主观题，标记为需要人工判卷
                    manualGradedCount++;
                    log.debug("主观题跳过自动判卷 - 题目ID: {}, 类型: {}", answer.getQuestionId(), question.getQuestionType());
                }

            } catch (Exception e) {
                log.error("判卷过程中发生错误 - 答案ID: {}, 错误: {}", answer.getAnswerId(), e.getMessage(), e);
                // 发生错误时，将该题标记为需要人工判卷
                manualGradedCount++;
            }
        }

        // 3. 设置结果
        result.setAutoGradedQuestions(autoGradedCount);
        result.setManualGradedQuestions(manualGradedCount);
        result.setTotalScore(totalScore);
        result.setMaxScore(maxScore);

        log.info("自动判卷完成 - 考试ID: {}, 学生ID: {}, 自动判卷: {}, 人工判卷: {}, 总得分: {}/{}", 
                examId, studentId, autoGradedCount, manualGradedCount, totalScore, maxScore);

        return result;
    }


    private double gradeObjectiveQuestion(Question question, ExamAnswer answer, double maxPoints) {
        String questionType = question.getQuestionType();
        String studentAnswer = answer.getAnswerContent();

        if (studentAnswer == null || studentAnswer.trim().isEmpty()) {
            return 0.0; // 未作答
        }

        if (QuestionType.SINGLE_CHOICE.name().equals(questionType)) {
            return gradeSingleChoiceQuestion(question, studentAnswer, maxPoints);
        } else if (QuestionType.MULTIPLE_CHOICE.name().equals(questionType)) {
            return gradeMultipleChoiceQuestion(question, studentAnswer, maxPoints);
        }

        return 0.0;
    }

    /**
     * 判卷单选题
     */
    private double gradeSingleChoiceQuestion(Question question, String studentAnswer, double maxPoints) {
        List<QuestionOption> correctOptions = questionOptionsMapper.selectOptionsByQuestionId(question.getQuestionId())
                .stream()
                .filter(QuestionOption::getIsCorrect)
                .toList();

        if (correctOptions.isEmpty()) {
            log.warn("单选题没有正确答案 - 题目ID: {}", question.getQuestionId());
            return 0.0;
        }

        if (studentAnswer == null || studentAnswer.trim().isEmpty()) {
            return 0.0;
        }

        String correctAnswer = correctOptions.get(0).getOptionId().toString();

        if (correctAnswer.equals(studentAnswer.trim())) {
            return maxPoints;
        } else {
            return 0.0;
        }
    }

    /**
     * 判卷多选题
     */
    private double gradeMultipleChoiceQuestion(Question question, String studentAnswer, double maxPoints) {
        List<QuestionOption> correctOptions = questionOptionsMapper.selectOptionsByQuestionId(question.getQuestionId())
                .stream()
                .filter(QuestionOption::getIsCorrect)
                .toList();

        if (correctOptions.isEmpty()) {
            log.warn("多选题没有正确答案 - 题目ID: {}", question.getQuestionId());
            return 0.0;
        }

        // 解析学生答案（假设答案格式为逗号分隔的选项ID）
        Set<String> studentAnswerSet;
        if (studentAnswer == null || studentAnswer.trim().isEmpty()) {
            studentAnswerSet = Set.of();
        } else {
            studentAnswerSet = Set.of(studentAnswer.trim().split(","))
                    .stream()
                    .filter(s -> !s.trim().isEmpty())
                    .map(String::trim)
                    .collect(Collectors.toSet());
        }

        Set<String> correctAnswerSet = correctOptions.stream()
                .map(option -> option.getOptionId().toString())
                .collect(Collectors.toSet());

        if (studentAnswerSet.equals(correctAnswerSet)) {
            return maxPoints;
        } else {
            return 0.0;
        }
    }

    /**
     * 更新答案分数
     */
    private void updateAnswerScore(Long answerId, double score, Long gradedBy, LocalDateTime gradedAt, String comments) {
        examAnswersMapper.updateAnswerScore(
                answerId,
                BigDecimal.valueOf(score),
                gradedBy,
                gradedAt,
                comments
        );
    }

    /**
     * 创建空结果
     */
    private AutoGradingResult createEmptyResult() {
        AutoGradingResult result = new AutoGradingResult();
        result.setTotalQuestions(0);
        result.setAutoGradedQuestions(0);
        result.setManualGradedQuestions(0);
        result.setTotalScore(0.0);
        result.setMaxScore(0.0);
        return result;
    }
}